using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
using GJXQGame;

    public interface IDataBase<TKey>
    {
        TKey GetID();
        bool ParseData(BinaryReader reader);
    }
    
    public class DataTable<TKey, TValue> where TValue : IDataBase<TKey>, new()
    {
        Dictionary<TKey, TValue> mMapTable = new Dictionary<TKey, TValue>();
        bool   mLoadRetValue;
        bool   mIsLoaded;
        string mFileName;

        public DataTable(string fileName)
        { 
            mFileName = fileName; 
        }

        public TValue this[TKey key] { get { return Find(key); } }

        public bool Load()
        {
            //if (mIsLoaded)
            //    return mLoadRetValue;
            mLoadRetValue = false;
            mIsLoaded = true;
            //string strPath = ConfigManager.RootPathResourcesConfig + mFileName.Substring(0, mFileName.Length - 6);
            string strPath = "Cache/Config/" + mFileName;
            TextAsset textAsset = ResourcesManager.GetInstance().LoadTextAsset(strPath);
            if (textAsset != null)
            {
                mLoadRetValue = true;
                MemoryStream ms = new MemoryStream(textAsset.bytes);
                BinaryReader reader = new BinaryReader(ms);
                //int count = reader.ReadInt32();
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    TValue record = new TValue();
                    if (!record.ParseData(reader))
                    {
                        mLoadRetValue = false;
                        break;
                    }

                    if (mMapTable.ContainsKey(record.GetID()))
                    {
                        mLoadRetValue = false;
                        break;
                    }
                    mMapTable.Add(record.GetID(), record);
                }
            }
            return mLoadRetValue;
        }

        public IEnumerator CoroutineLoad()
        {
            //if (mIsLoaded) yield return false;

            mLoadRetValue = false;
            mIsLoaded = true;

            yield return GameRoot.StartCoroutine(ResourcesManager.CoroutineLoad(Global.LOCAL_RES_Path + "Config/" + mFileName, loader =>
            //yield return GameRoot.StartCoroutine(ResourcesManager.CoroutineLoad("Cache/Config/" + mFileName, loader =>
            {
                if (true&& !string.IsNullOrEmpty(loader.error))
                {
                    Load();
                    return;
                }
                mLoadRetValue = true;
                MemoryStream ms = new MemoryStream(loader.bytes);
                BinaryReader reader = new BinaryReader(ms);
                int count = reader.ReadInt32();
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    TValue record = new TValue();
                    if (!record.ParseData(reader))
                    {
                        mLoadRetValue = false;
                        break;
                    }

                    if (mMapTable.ContainsKey(record.GetID()))
                    {
                        mLoadRetValue = false;
                        GameLog.Log("ID repeated asshole!!! " + mFileName + ": " + record.GetID());
                        break;
                    }

                    mMapTable.Add(record.GetID(), record);
                }
            }));
        }

        public TValue Find(TKey key)
        {
            if (mMapTable.ContainsKey(key))
            {
                return mMapTable[key];
            }
            return default(TValue);
        }

        public int Size()
        {
            return mMapTable.Count;
        }

        public Dictionary<TKey, TValue> MapTable
        {
            get { return mMapTable; }
        }
    }
